package com.zhiche.lisa.bms.service.driver.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.zhiche.lisa.bms.dao.mapper.driver.RouteMapper;
import com.zhiche.lisa.bms.dao.model.driver.PriceconfFreight;
import com.zhiche.lisa.bms.dao.model.driver.PriceconfMile;
import com.zhiche.lisa.bms.dao.model.driver.Route;
import com.zhiche.lisa.bms.service.driver.IPriceconfFreightService;
import com.zhiche.lisa.bms.service.driver.IPriceconfMileService;
import com.zhiche.lisa.bms.service.driver.IRouteService;
import com.zhiche.lisa.bms.pojo.vo.driver.RouteVO;
import com.zhiche.lisa.core.supports.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 线路表 服务实现类
 * </p>
 *
 * @author zhaoguixin
 * @since 2018-08-30
 */
@Service
@Slf4j
public class RouteServiceImpl extends ServiceImpl<RouteMapper, Route> implements IRouteService {

    @Autowired
    private IPriceconfMileService priceconfMileService;

    @Autowired
    private IPriceconfFreightService priceconfFreightService;

    /**
     * 分页查询线路
     *
     * @param pageVO
     * @return
     */
    @Override
    public Page<RouteVO> listByPage(Page<RouteVO> pageVO) {
        if (pageVO == null) return null;
        pageVO.setOrderByField("update_time");
        pageVO.setAsc(false);
        EntityWrapper<Route> ew = whereRouteCondition(pageVO);
        List<Route> listRoute = baseMapper.selectPage(pageVO,ew);
        List<RouteVO> listVO = Lists.newArrayList();
        listRoute.forEach(route -> {
            RouteVO routeVO = new RouteVO();
            BeanUtils.copyProperties(route,routeVO);
            listVO.add(routeVO);
        });
        pageVO.setRecords(listVO);
        return pageVO;
    }

    /**
     * 查询条件
     * @param page
     * @return
     */
    private EntityWrapper<Route> whereRouteCondition(Page<RouteVO> page){
        EntityWrapper<Route> ew = new EntityWrapper<>();

        //查询条件
        if (Objects.nonNull(page.getCondition())){
            //起运省
            if (Objects.nonNull(page.getCondition().get("oProvinceCode")) && StringUtils.isNotEmpty(page.getCondition().get("oProvinceCode").toString())) {
                ew.eq("o_province_code", page.getCondition().get("oProvinceCode").toString().trim());
            }
            // 起始地标签
            if (Objects.nonNull(page.getCondition().get("oTag")) && StringUtils.isNotEmpty(page.getCondition().get("oTag").toString())){
                ew.like("o_tag", page.getCondition().get("oTag").toString().trim());
            }
            //起运市
            if (Objects.nonNull(page.getCondition().get("oCityCode")) && StringUtils.isNotEmpty(page.getCondition().get("oCityCode").toString())) {
                ew.eq("o_city_code", page.getCondition().get("oCityCode").toString().trim());
            }
            //起运区县
            if (Objects.nonNull(page.getCondition().get("oCountyCode")) && StringUtils.isNotEmpty(page.getCondition().get("oCountyCode").toString())) {
                ew.eq("o_county_code", page.getCondition().get("oCountyCode").toString().trim());
            }
            //目的省
            if (Objects.nonNull(page.getCondition().get("dProvinceCode")) && StringUtils.isNotEmpty(page.getCondition().get("dProvinceCode").toString())) {
                ew.eq("d_province_code", page.getCondition().get("dProvinceCode").toString().trim());
            }
            //目的市
            if (Objects.nonNull(page.getCondition().get("dCityCode")) && StringUtils.isNotEmpty(page.getCondition().get("dCityCode").toString())) {
                ew.eq("d_city_code", page.getCondition().get("dCityCode").toString().trim());
            }
            //目的区县
            if (Objects.nonNull(page.getCondition().get("dCountyCode")) && StringUtils.isNotEmpty(page.getCondition().get("dCountyCode").toString())) {
                ew.eq("d_county_code", page.getCondition().get("dCountyCode").toString().trim());
            }
            //目的地标签
            if (Objects.nonNull(page.getCondition().get("dTag")) && StringUtils.isNotEmpty(page.getCondition().get("dTag").toString())) {
                ew.like("d_tag", page.getCondition().get("dTag").toString().trim());
            }
            //线路名称
            if (Objects.nonNull(page.getCondition().get("name")) && StringUtils.isNotEmpty(page.getCondition().get("name").toString())) {
                ew.like("name", page.getCondition().get("name").toString().trim());
            }

            if (Objects.nonNull(page.getCondition().get("routeName")) && StringUtils.isNotEmpty(page.getCondition().get("routeName").toString())) {
                ew.orNew().like("name", page.getCondition().get("routeName").toString().trim()).
                        or().like("d_tag",page.getCondition().get("routeName").toString().trim())
                        .or().like("o_tag",page.getCondition().get("routeName").toString().trim());
            }
        }
        return ew;
    }

    /**
     * 添加路线信息
     *
     * @param routeVO
     * @param br
     * @return
     */
    @Override
    public Integer add(RouteVO routeVO, BindingResult br) {
        log.info("RouteServiceImpl.add params : {}", routeVO);

        if (Objects.isNull(routeVO)) {
            log.error("RouteServiceImpl.add param routeVO must not be null");
            throw new BaseException("线路表单不能为空");
        }

        //验证表单
        verificationForm(br);

        /**
         * 判断线路是否唯一（起始市和目的地市）
         */
        List<Route> routes = this.verificationOTagAndDTagAndNameUnique(routeVO.getoTag(), routeVO.getdTag(), routeVO.getName());
        if (CollectionUtils.isNotEmpty(routes)) {
            log.error("RouteServiceImpl.add error routes is not empty ");
            throw new BaseException("线路已存在！");
        }

        Route route = new Route();
        BeanUtils.copyProperties(routeVO, route);
        route.setEnable(1);

        this.insert(route);

        return route.getId();
    }

    /**
     * 更新线路信息
     *
     * @param routeVO
     * @param br
     * @return
     */
    @Override
    public Boolean update(RouteVO routeVO, BindingResult br) {
        log.info("RouteServiceImpl.update params : {}", routeVO);

        if (Objects.isNull(routeVO)) {
            log.error("RouteServiceImpl.update param form must not be null");
            throw new BaseException("线路表单不能为空");
        }

        //验证表单
        verificationForm(br);

        /**
         * 判断线路是否唯一（起始市和目的地市）
         */
        List<Route> routes = this.verificationOTagAndDTagAndNameUnique(routeVO.getoTag(), routeVO.getdTag(), routeVO.getName());
        if (CollectionUtils.isNotEmpty(routes)) {
            if (routes.size() > 1) {
                log.error("RouteServiceImpl.add error routes is not empty ");
                throw new BaseException("线路已存在！");
            } else {
                if (null != routeVO.getId() && !routeVO.getId().equals(routes.get(0).getId())) {
                    log.error("RouteServiceImpl.add error routes is not empty ");
                    throw new BaseException("线路已存在！");
                }
            }
        }

        Route route = new Route();
        BeanUtils.copyProperties(routeVO, route);
        return this.updateById(route);
    }

    /**
     * 更新线路可用还是不可用
     *
     * @param id
     * @param enableOrDisabled
     * @return
     */
    @Override
    public Boolean enableOrDisabled(Integer id, Boolean enableOrDisabled) {
        log.info("RouteServiceImpl.enableOrDisabled params : {}, {}", id, enableOrDisabled);
        if(Objects.isNull(id)){
            log.error("线路编码ID为空");
        }
        Route route = this.selectById(id);
        if(Objects.isNull(route)){
            log.error("线路信息不存在");
            throw new BaseException("线路信息不存在");
        }

        if(enableOrDisabled){
            route.setEnable(1);
        }
        else{
            route.setEnable(0);
        }
       return this.updateById(route);
    }

    /**
     * 删除线路信息
     *
     * @param id
     * @throws Exception
     */
    @Override
    public Boolean del(Integer id) throws BaseException {
        log.info("RouteServiceImpl.del param : {}", id);

        if (Objects.isNull(id) || id.equals(0)) {
            log.error("RouteServiceImpl.del param id must not be null");
            throw new BaseException("主键不能为空");
        }

        Route route = this.selectById(id);
        if(Objects.isNull(route)){
            throw new BaseException("线路信息为空");
        }

        /**
         * 验证是否更里程变更有关联
         */
        EntityWrapper<PriceconfMile> ewPriceMile = new EntityWrapper<>();
        ewPriceMile.eq("route_id",id);
        List<PriceconfMile> mileList = priceconfMileService.selectList(ewPriceMile);
        if (CollectionUtils.isNotEmpty(mileList) ) {
            log.error("DRouteServiceImpl.del associated with mile");
            throw new BaseException("请先移除线路里程变更的关联");
        }

        /**
         * 验证是否更价格变更有关联
         */
        EntityWrapper<PriceconfFreight> ewPircefFreight = new EntityWrapper<>();
        ewPircefFreight.eq("route_id",id);
        List<PriceconfFreight> priceconfFreightList = priceconfFreightService.selectList(ewPircefFreight);
        if (CollectionUtils.isNotEmpty(priceconfFreightList) ) {
            log.error("DRouteServiceImpl.del associated with freight");
            throw new BaseException("请先移除线路价格变更的关联");
        }

        return this.deleteById(id);

    }

    /**
     * 根据id得到线路信息
     *
     * @param id
     * @return
     */
    @Override
    public RouteVO getById(Integer id) {
        RouteVO routeVO = new RouteVO();
        Route route = this.selectById(id);
        BeanUtils.copyProperties(route,routeVO);
        return routeVO;
    }

    /**
     * 验证表单
     * @param br
     */
    private void verificationForm(BindingResult br) {
        if (Objects.isNull(br)) {
            log.error("RouteServiceImpl.verificationForm error br is null");
            throw new BaseException("BindingResult is null");
        }

        if (br.hasErrors()) {
            List<ObjectError> list = br.getAllErrors();
            log.error("RouteServiceImpl.add error : {}", list.get(0).getDefaultMessage());
            throw new BaseException(list.get(0).getDefaultMessage());
        }
    }


    /**
     * 判断是否存在
     * @param oTag
     * @param dTag
     * @param routeName
     * @return
     */
    private List<Route> verificationOTagAndDTagAndNameUnique(String oTag, String dTag, String routeName) {
        log.info("RouteServiceImpl.selectByOCityCodeAndDCityCode params : {}, {}", oTag, dTag);

        if (StringUtils.isBlank(oTag)) {
            log.error("RouteServiceImpl.selectByOCityCodeAndDCityCodeAndName param oTag must not be null");
            throw new BaseException("起始地市不能为空");
        }
        if (StringUtils.isBlank(dTag)) {
            log.error("RouteServiceImpl.selectByOCityCodeAndDCityCodeAndName param dTag must not be null");
            throw new BaseException("目的地市不能为空");
        }
        if (StringUtils.isBlank(routeName)) {
            log.error("RouteServiceImpl.selectByOCityCodeAndDCityCodeAndName param routeName must not be null");
            throw new BaseException("线路名称不能为空");
        }


        EntityWrapper<Route> ew1 = new EntityWrapper<>();
        ew1.eq("name",routeName);
        List<Route> list = this.selectList(ew1);

        if (CollectionUtils.isEmpty(list)) {
            EntityWrapper<Route> ew = new EntityWrapper<>();
            ew.eq("o_tag", oTag).eq("d_tag", dTag);
            list = this.selectList(ew);
        }

        return list;
    }

    /**
     * 根据关键字得到起点区域
     *
     * @param keyword
     * @return
     */
    @Override
    public List<String> getOTagsByKey(String keyword) {
        EntityWrapper<Route> ew = new EntityWrapper<>();
        ew.like("o_tag",keyword);
        List<String> list = this.selectList(ew).stream().map(Route::getoTag).distinct().collect(Collectors.toList());
        return  list;
    }

    /**
     * 根据关键字得到终点区域
     *
     * @param keyword
     * @return
     */
    @Override
    public List<String> getDTagsByKey(String keyword) {
        EntityWrapper<Route> ew = new EntityWrapper<>();
        ew.like("d_tag",keyword);
        List<String> list = this.selectList(ew).stream().map(Route::getdTag).distinct().collect(Collectors.toList());
        return  list;
    }

    /**
     * 根据关键字得到线路
     *
     * @param keyword
     * @return
     */
    @Override
    public List<RouteVO> listByKeyword(String keyword) {
       EntityWrapper<Route> ew = new EntityWrapper<>();
       ew.like("name",keyword);
       List<Route> list = this.selectList(ew);
       List<RouteVO> listVO = Lists.newArrayList();
       list.forEach(route -> {
           RouteVO routeVO = new RouteVO();
           BeanUtils.copyProperties(route,routeVO);
           listVO.add(routeVO);
       });
       return listVO;
    }
}
